import java.io.Console;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.System.err;
import static java.lang.System.out;

public final class HumanPlayer extends Player {
    private static Pattern movePattern;

    private Console console;

    static {
        String square = "(?:[12]?\\d|3[0-2])";
        String regex = "^\\s*"+square+"(?:\\s*-\\s*"+square+")+\\s*$";
        movePattern = Pattern.compile(regex);
    }

    public HumanPlayer(boolean isBlack) {
        super(isBlack);
        console = System.console();
        if (console == null) {
            throw new RuntimeException("Couldn't find a console to read input"
                                       + " from.");
        }
    }

    @Override
    public Action getMove(Board board, int moveNbr) {
        long startTime = System.currentTimeMillis();

        Action action = null;
        while (action == null) {
            String input = console.readLine("What is %s's move %d: ", color,
                                            moveNbr);
            if (input == null) {
                out.println();
                return new Action(Actions.QUIT);
            }
            assert input != null;

            String command = input.trim();
            if (command.equalsIgnoreCase("help")) {
                out.println("Available commands are:");
                out.println("help - print this help.");
                out.println("quit - quit the game.");
                out.println("back - undo the last move for both players and let"
                            + " the current player type");
                out.println("       in a new move instead of the last move.");
                out.println("Moves are written like: 11-15.");
                out.println("Jumps are written like: 9-18-27.");

                startTime = System.currentTimeMillis();
            } else if (command.equalsIgnoreCase("quit")) {
                action = new Action(Actions.QUIT);
            } else if (command.equalsIgnoreCase("back")) {
                action = new Action(moveNbr - 1, board.blackToMove);
            } else {
                int[] move = parseMove(command);

                if (move == null) {
                    out.println("I'm sorry, but I don't understand what you are"
                                + " saying.");
                    out.println("Please write your moves as: 11 - 15.");
                    out.println("Valid squares are numbered 1 - 32.");
                } else {
                    long endTime = System.currentTimeMillis();
                    long thisMove = endTime - startTime;
                    spentTime += thisMove;
                    action = new Action(move, spentTime);
                }
            }
        }

        return action;
    }

    //Check that the input is of valid form
    public static int[] parseMove(String input) {
        Matcher m = movePattern.matcher(input);
        if (!m.matches()) {
            return null;
        }
        //Split string to extract board locations
        String match = m.group();
        //out.println("Match: " + match);
        String[] ints = match.trim().split("\\s*-\\s*");
        //String[] to int[]
        int[] move = new int[ints.length];
        for(int i = 0; i < ints.length; i++){
            move[i] = Integer.parseInt(ints[i]);
        }
        //for(int i : move) out.print(i+" ");

        return move;
    }
}
